<template>
    <Search v-if='search' :fields='searchFields' :buttons='buttons' :loading='loading' @search='doSeach'>
        <template #button>
            <template v-if='slots["$button"]'>
                <template v-for='(vnode, index) in slots["$button"]()' :key='index'>
                    <component :is='vnode' />
                </template>
            </template>
        </template>
    </Search>
    
    <div :class='{"m-t-20" : search}'>
        <BT ref="tableRef" :columns='columns' :data='dataList' v-bind='attrs' :rowSelection='rowSelection' :selection-buttons="selectionButtons" :rowKey="rowKey" :nameKey='nameKey' @selectionChange="selectionChange">
            <template v-for='(slot, key) in slots' :key='key' v-slot:[key]='e'>
                <template v-if='key != "$button"'>
                    <template v-for='(vnode, index) in slot(e)' :key='index'>
                        <component :is='vnode' />
                    </template>
                </template>
            </template>
        </BT>
        <div class='m-t-48'>
            <Pagination ref='paginationRef' :api='page' @finish='pageFinish' />
        </div>
    </div>
</template>

<script lang='ts' setup>
import { toRefs, computed, nextTick, reactive, ref, useSlots } from "vue"
import Search from './Search.vue'
import Pagination from './Pagination.vue'
import BT from './Table.vue'

    const props = withDefaults(defineProps<{
        selectedRows : any[];
        rowSelection? : object | boolean;
        rowKey? : string;
        nameKey? : string;
        api : (params:any) => any;
        columns : Column[];
        search : boolean;
        buttons? : Array<SearchButton>,
        selectionButtons? : Array<SelectionButton>,
        [key:string] : any;
    }>(), {
        search : true,
        rowSelection : false
    })

    const emit = defineEmits<{
        (e : 'selectionChange', keys:any[], rows : any[]) : void;
    }>()

    const { columns, rowSelection, nameKey, ...attrs } = toRefs(props)

    const slots = useSlots()

    const searchFields = computed(() => {
        return columns.value.filter(column => column.inSearch)
    })

    const queryParams = ref<any>({})
    const loading = ref(false)
    const dataList = reactive<any[]>([])
    const paginationRef = ref()
    const tableRef = ref()

    
    async function page(params:any) {
        loading.value = true
        const res = await props.api({...params, ...queryParams.value}) 
        loading.value = false
        return res
    }

    function pageFinish(rows:any[]) {
        dataList.splice(0)
        dataList.push(...rows) 
    }

    function doSeach(params:any) {
        queryParams.value = params
        nextTick(() => {
            paginationRef.value.reload()
        })
        
    }

    function selectionChange(keys:any[], rows:any[]) {
        emit('selectionChange', keys, rows)
    }

    defineExpose({
        load() {
            tableRef.value.cleanSelection()
            paginationRef.value.load()
        },
        reload() {
            tableRef.value.cleanSelection()
            paginationRef.value.reload()
        }
    })




</script>